1   /*
2    * Copyright (C) 2007 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect;
18  
19  import com.google.common.annotations.GwtCompatible;
20  
21  import java.util.Collection;
22  import java.util.Collections;
23  import java.util.Comparator;
24  import java.util.Map;
25  import java.util.SortedSet;
26  
27  import javax.annotation.Nullable;
28  
29  /**
30   * Basic implementation of the {@link SortedSetMultimap} interface. It's a
31   * wrapper around {@link AbstractMapBasedMultimap} that converts the returned
32   * collections into sorted sets. The {@link #createCollection} method
33   * must return a {@code SortedSet}.
34   *
35   * @author Jared Levy
36   */
37  @GwtCompatible
38  abstract class AbstractSortedSetMultimap<K, V>
39      extends AbstractSetMultimap<K, V> implements SortedSetMultimap<K, V> {
40    /**
41     * Creates a new multimap that uses the provided map.
42     *
43     * @param map place to store the mapping from each key to its corresponding
44     *     values
45     */
46    protected AbstractSortedSetMultimap(Map<K, Collection<V>> map) {
47      super(map);
48    }
49  
50    @Override
51    abstract SortedSet<V> createCollection();
52  
53    @Override
54    SortedSet<V> createUnmodifiableEmptyCollection() {
55      Comparator<? super V> comparator = valueComparator();
56      if (comparator == null) {
57        return Collections.unmodifiableSortedSet(createCollection());
58      } else {
59        return ImmutableSortedSet.emptySet(valueComparator());
60      }
61    }
62  
63    // Following Javadoc copied from Multimap and SortedSetMultimap.
64  
65    /**
66     * Returns a collection view of all values associated with a key. If no
67     * mappings in the multimap have the provided key, an empty collection is
68     * returned.
69     *
70     * <p>Changes to the returned collection will update the underlying multimap,
71     * and vice versa.
72     *
73     * <p>Because a {@code SortedSetMultimap} has unique sorted values for a given
74     * key, this method returns a {@link SortedSet}, instead of the
75     * {@link Collection} specified in the {@link Multimap} interface.
76     */
77    @Override public SortedSet<V> get(@Nullable K key) {
78      return (SortedSet<V>) super.get(key);
79    }
80  
81    /**
82     * Removes all values associated with a given key. The returned collection is
83     * immutable.
84     *
85     * <p>Because a {@code SortedSetMultimap} has unique sorted values for a given
86     * key, this method returns a {@link SortedSet}, instead of the
87     * {@link Collection} specified in the {@link Multimap} interface.
88     */
89    @Override public SortedSet<V> removeAll(@Nullable Object key) {
90      return (SortedSet<V>) super.removeAll(key);
91    }
92  
93    /**
94     * Stores a collection of values with the same key, replacing any existing
95     * values for that key. The returned collection is immutable.
96     *
97     * <p>Because a {@code SortedSetMultimap} has unique sorted values for a given
98     * key, this method returns a {@link SortedSet}, instead of the
99     * {@link Collection} specified in the {@link Multimap} interface.
100    *
101    * <p>Any duplicates in {@code values} will be stored in the multimap once.
102    */
103   @Override public SortedSet<V> replaceValues(
104       @Nullable K key, Iterable<? extends V> values) {
105     return (SortedSet<V>) super.replaceValues(key, values);
106   }
107 
108   /**
109    * Returns a map view that associates each key with the corresponding values
110    * in the multimap. Changes to the returned map, such as element removal, will
111    * update the underlying multimap. The map does not support {@code setValue}
112    * on its entries, {@code put}, or {@code putAll}.
113    *
114    * <p>When passed a key that is present in the map, {@code
115    * asMap().get(Object)} has the same behavior as {@link #get}, returning a
116    * live collection. When passed a key that is not present, however, {@code
117    * asMap().get(Object)} returns {@code null} instead of an empty collection.
118    *
119    * <p>Though the method signature doesn't say so explicitly, the returned map
120    * has {@link SortedSet} values.
121    */
122   @Override public Map<K, Collection<V>> asMap() {
123     return super.asMap();
124   }
125 
126   /**
127    * {@inheritDoc}
128    *
129    * Consequently, the values do not follow their natural ordering or the
130    * ordering of the value comparator.
131    */
132   @Override public Collection<V> values() {
133     return super.values();
134   }
135 
136   private static final long serialVersionUID = 430848587173315748L;
137 }